﻿using Kang.DbDoc.Enums;
using System.Collections.ObjectModel;
using System.Data.SqlClient;
using CommunityToolkit.Mvvm.ComponentModel;
using Npgsql;
using Kang.DbDoc.Interfaces;
using Kang.ExtendMethod;
using Microsoft.Data.Sqlite;
using MySql.Data.MySqlClient;
using Oracle.ManagedDataAccess.Client;
using Kang.DbDoc.ServicesImpl;

namespace Kang.DbDoc.Models
{
    public class DatabaseModel : ObservableObject
    {
        private IConnectionService connectionService;

        private int _id;
        /// <summary>
        /// Id
        /// </summary>
        public int Id
        {
            get
            {
                return _id;
            }
            set
            {
                SetProperty(ref _id, value);
            }
        }

        private DatabaseTypeEnum? _databaseType;
        /// <summary>
        /// 数据库类型
        /// </summary>
        public DatabaseTypeEnum? DatabaseType
        {
            get
            {
                return _databaseType;
            }
            set
            {
                SetProperty(ref _databaseType, value);
            }
        }

        private string _name;
        /// <summary>
        /// 连接名称
        /// </summary>
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                SetProperty(ref _name, value);
            }
        }

        private string _databaseName;
        /// <summary>
        /// 数据库名称
        /// </summary>
        public string DatabaseName
        {
            get
            {
                return _databaseName;
            }
            set
            {
                SetProperty(ref _databaseName, value);
            }
        }

        private string _databaseHost;
        /// <summary>
        /// 数据库地址
        /// </summary>
        public string DatabaseHost
        {
            get
            {
                return _databaseHost;
            }
            set
            {
                SetProperty(ref _databaseHost, value);
            }
        }

        private int _databasePort;
        /// <summary>
        /// 数据库端口
        /// </summary>
        public int DatabasePort
        {
            get
            {
                return _databasePort;
            }
            set
            {
                SetProperty(ref _databasePort, value);
            }
        }

        private string _databaseUsername;
        /// <summary>
        /// 数据库用户名称
        /// </summary>
        public string DatabaseUsername
        {
            get
            {
                return _databaseUsername;
            }
            set
            {
                SetProperty(ref _databaseUsername, value);
            }
        }

        private string _databasePassword;
        /// <summary>
        /// 数据库密码
        /// </summary>
        public string DatabasePassword
        {
            get
            {
                return _databasePassword;
            }
            set
            {
                SetProperty(ref _databasePassword, value);
            }
        }

        private int _timeOut;
        /// <summary>
        /// 数据库密码
        /// </summary>
        public int TimeOut
        {
            get
            {
                return _timeOut;
            }
            set
            {
                SetProperty(ref _timeOut, value);
            }
        }

        private bool _isSslMode;
        /// <summary>
        /// 数据库密码
        /// </summary>
        public bool IsSslMode
        {
            get
            {
                return _isSslMode;
            }
            set
            {
                SetProperty(ref _isSslMode, value);
            }
        }

        private string _connectionString;
        /// <summary>
        /// 连接字串
        /// </summary>
        public string ConnectionString
        {
            get
            {
                return _connectionString;
            }
            set
            {
                SetProperty(ref _connectionString, value);
            }
        }

        private string _remark;
        /// <summary>
        /// 备注
        /// </summary>
        public string Remark
        {
            get
            {
                return _remark;
            }
            set
            {
                SetProperty(ref _remark, value);
            }
        }

        /// <summary>
        /// 数据库所包含的表信息
        /// </summary>
        public ObservableCollection<TableOrViewModel> _tables = new ObservableCollection<TableOrViewModel>();
        public ObservableCollection<TableOrViewModel> Tables
        {
            get
            {
                return _tables;
            }
            set
            {
                SetProperty(ref _tables, value);
            }
        }

        /// <summary>
        /// 数据库所包含的视图信息
        /// </summary>
        public ObservableCollection<TableOrViewModel> Views { get; set; } = new ObservableCollection<TableOrViewModel>();

        /// <summary>
        /// 数据库所包含的方法信息
        /// </summary>
        public ObservableCollection<RoutineModel> Functions { get; set; } = new ObservableCollection<RoutineModel>();

        /// <summary>
        /// 数据库所包含的存储过程信息
        /// </summary>
        public ObservableCollection<RoutineModel> Procedures { get; set; } = new ObservableCollection<RoutineModel>();

        public DatabaseModel(DatabaseTypeEnum? DatabaseType)
        {
            this.DatabaseType = DatabaseType;
            RefreshConnectionService(DatabaseType);
            connectionService?.SetDefault(this);
        }

        public void Load(string SearchWord)
        {
            connectionService?.LoadDatabaseData(this, SearchWord);
        }

        public void SetDefaultValue()
        {
            connectionService?.SetDefault(this);
        }

        public void SetDefaultValue(DatabaseTypeEnum? DatabaseType)
        {
            RefreshConnectionService(DatabaseType);
            connectionService?.SetDefault(this);
        }

        public void RefreshConnectionService(DatabaseTypeEnum? DatabaseType)
        {
            switch (DatabaseType)
            {
                case DatabaseTypeEnum.SqlServer:
                    connectionService = new SqlServerConnectionService();
                    break;
                case DatabaseTypeEnum.MySql:
                    connectionService = new MySqlConnectionService();
                    break;
                case DatabaseTypeEnum.Oracle:
                    connectionService = new OracleConnectionService();
                    break;
                case DatabaseTypeEnum.SQLite:
                    connectionService = new SQLiteConnectionService();
                    break;
                case DatabaseTypeEnum.PostgreSQL:
                    connectionService = new PostgreSQLConnectionService();
                    break;
            }
        }

        public void RefreshConnectionString()
        {
            ConnectionString = connectionService?.GetConnectionString(this);
        }
    }
}
